home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
smailsrc.zip
/
UUPC.ZIP
/
DCPSYS.C
< prev
next >
Wrap
Text File
|
1990-04-21
|
14KB
|
742 lines
/*
* 8 space tabs for this file
*/
/*
dcpsys.c
Revised edition of dcp
Stuart Lynne May/87
Copyright (c) Richard H. Lamb 1985, 1986, 1987
Changes Copyright (c) Stuart Lynne 1987
*/
/* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */
/* Support routines */
#include "ndir.h"
#include "dcp.h"
#define MAXLOGTRY 3
#define TIMEOUT -1
#define PROTOS "g" /* available protocoles */
Proto Protolst[] = {
'g', ggetpkt, gsendpkt, gopenpk, gclosepk,
'\0'};
#define EOTMSG "\004\r\004\r"
procref getpkt, sendpkt, openpk, closepk;
static char *flds[60];
static int kflds;
static char proto[5];
static char S_sysline[BUFSIZ], S_sysdevice[16], S_sysspeed[16];
extern void wmsg();
extern int rmsg();
static void setproto();
static int checktime();
/****************************************/
/* Sub Systems */
/****************************************/
/*
g e t s y s t e m
Process a systems file (L.sys) entry.
Null lines or lines starting with '#' are comments.
*/
char getsystem()
{
do { /* flush to next non-comment line */
if (fgets(S_sysline, BUFSIZ, fsys) == nil(char))
return 'A'; /* end-of-file */
} while ((*S_sysline == '\0') || (*S_sysline == '\n') || (*S_sysline == '#'));
printmsg(8, "sysline=\"%s\"", S_sysline);
kflds = getargs(S_sysline, flds);
strcpy(rmtname, flds[FLD_REMOTE]);
strcpy(S_sysdevice, flds[FLD_DEVICE]);
/* strcpy(type, flds[FLD_TYPE]); */
strcpy(S_sysspeed, flds[FLD_SPEED]);
strcpy(proto, flds[FLD_PROTO]);
if (debuglevel >= 4) {
int i;
for (i = FLD_EXPECT; i < kflds; i += 2)
printmsg(6, "expect [%02d]:\t%s\nsend [%02d]:\t%s",
i, flds[i], i + 1, flds[i + 1]);
}
printmsg(2, "remote=%s, call-time=%s,", rmtname, flds[FLD_CCTIME]);
printmsg(2, "device=%s, speed=%s, protocol=%s",
S_sysdevice, S_sysspeed, proto);
fwork = nil(FILE);
if (checktime(flds[FLD_CCTIME]) && (
equal(Rmtname, "all") ||
equaln(Rmtname, rmtname, 7) ||
(equal(Rmtname, "any") && scandir(rmtname) == 'S'))) {
if (fwork != nil(FILE)) /* in case matched with scandir */
fclose(fwork);
return 'S'; /* startup this system */
} else
return 'G';
} /*getsystem*/
/*
c h e c k n a m e
Look up a system name in our systems (L.sys) file.
Only the first 7 characters of a system name is significant.
*/
static int checkname(name)
char *name;
{
FILE *ff;
char line[BUFSIZ];
if ((ff = FOPEN(s_systems, "r", TEXT)) == nil(FILE))
return FAILED;
while (fgets(line, BUFSIZ, ff) != nil(char)) {
printmsg(3, "checkname: got '%s', want '%s'", line, name);
if (equaln(name, line, 7)) {
fclose(ff);
return OK; /* OK, we like you */
}
}
fclose(ff);
return FAILED; /* Who are you? */
} /*checkname*/
/*
c h e c k t i m e
Check if we may make a call at this time
*** to be implemented. Again, didn't think it crucial.
*/
static int checktime(xtime)
char *xtime;
{
printmsg(2, "checktime: %s", xtime);
return TRUE; /* OK, go to it */
} /*checktime*/
/*
s y s e n d
End UUCP session negotiation
*/
char sysend()
{
char msg[80];
msg[1] = '\0';
msgtime = 2 * MSGTIME;
/* while (msg[1] != 'O') { */
wmsg("OOOOOO", TRUE);
if (rmsg(msg, TRUE) == TIMEOUT)
goto hang;
/*}*/
hang:
wmsg("OOOOOO", TRUE);
closeline();
return (remote == MASTER) ? 'I' : 'A';
} /*sysend*/
/*
w m s g
write a ^P type msg to the remote uucp
*/
void wmsg(msg, synch)
char *msg;
int synch;
{
if (synch)
swrite("\0\020", 2);
swrite(msg, strlen(msg));
if (synch)
swrite("\0", 1);
} /*wmsg*/
/*
r m s g
read a ^P msg from UUCP
*/
int rmsg(msg, synch)
char *msg;
int synch;
{
int i;
char ch;
/* flush until next ^P */
if (synch)
do
if (sread(&ch, 1, msgtime) < 1)
return TIMEOUT;
while ((ch & 0x7f) != '\020');
for (i = 0; (i < 132) && (ch != '\0'); ) {
if (sread(&ch, 1, msgtime) < 1)
return TIMEOUT;
ch &= 0x7f;
if (ch == '\r' || ch == '\n')
ch = '\0';
msg[i++] = ch;
}
return strlen(msg);
} /*rmsg*/
/*
s t a r t u p
*/
char startup()
{
char msg[80];
if (remote == MASTER) {
msgtime = 2 * MSGTIME;
if (rmsg(msg, TRUE) == TIMEOUT)
return 'Y';
printmsg(2, "1st msg = %s", msg);
if (msg[5] == '=' && !equaln(&msg[6], rmtname, 7))
return 'Y'; /* wrong host */
/* sprintf(msg, "S%.7s -Q0 -x%d", nodename, debuglevel); */
/* -Q0 -x16 remote debuglevel set */
sprintf(msg, "S%.7s", nodename);
wmsg(msg, TRUE);
if (rmsg(msg, TRUE) == TIMEOUT)
return 'Y';
printmsg(2, "2nd msg = %s", msg);
if (!equaln(&msg[1], "OK", 2))
return 'Y';
if (rmsg(msg, TRUE) == TIMEOUT)
return 'Y';
printmsg(2, "3rd msg = %s", msg);
if (msg[0] != 'P' || (strchr(&msg[1], proto[0]) == nil(char))) {
wmsg("UN", TRUE);
return 'Y'; /* no common protocol */
} else {
sprintf(msg, "U%c", proto[0]);
wmsg(msg, TRUE);
}
setproto(proto[0]);
return 'D';
} else {
char tmp1[20], tmp2[20];
msgtime = 2 * MSGTIME;
sprintf(msg, "Shere=%s", nodename);
wmsg(msg, TRUE);
if (rmsg(msg, TRUE) == TIMEOUT)
return 'Y';
sscanf(&msg[1], "%s %s %s", rmtname, tmp1, tmp2);
sscanf(tmp2, "-x%d", &debuglevel);
printmsg(1, "debuglevel set to %d by remote", debuglevel);
printmsg(2, "1st msg from remote = %s", msg);
if (checkname(rmtname))
return 'Y';
wmsg("ROK", TRUE);
sprintf(msg, "P%s", PROTOS);
wmsg(msg, TRUE);
if (rmsg(msg, TRUE) == TIMEOUT)
return 'Y';
if (msg[0] != 'U' || (strchr(PROTOS, msg[1]) == nil(char)))
return 'Y';
proto[0] = msg[1];
setproto(proto[0]);
return 'R';
}
} /*startup*/
/*
s e t p r o t o
set the protocol to be used
*/
static void setproto(wanted)
char wanted;
{
Proto *tproto;
for (tproto = Protolst;
tproto->type != '\0' && tproto->type != wanted;
tproto++) {
printmsg(3, "setproto: wanted '%c', have '%c'", wanted, tproto->type);
}
if (tproto->type == '\0') {
printmsg(0, "setproto: You said I have it but I cant find it!");
exit(1);
}
getpkt = tproto->a;
sendpkt = tproto->b;
openpk = tproto->c;
closepk = tproto->d;
} /*setproto*/
#define prefix(small,large) (equaln((small), (large), strlen(small)))
#define notin(str,log) (strstr((log), (str)) == nil(char))
/*
e x p e c t s t r
*/
#define MAXHIST 300
int expectstr(str, timeout)
char *str;
int timeout;
{
static char history[MAXHIST];
char *rp = history;
printmsg(1, "wanted %s", str);
if (equal(str, "\"\"")) /* expects nothing */
return TRUE;
*rp = 0;
while (notin(str, history)) {
char ch;
if (sread(&ch, 1, timeout) < 1)
return FALSE;
if ((*rp = (ch & 0x7f)) != '\0')
rp++;
*rp = '\0';
if (rp >= history + MAXHIST)
return FALSE;
}
return TRUE;
} /*expectstr*/
int writestr(s)
register char *s;
{
register char last;
int nocr;
last = '\0';
nocr = FALSE;
while (*s) {
if (last == '\\') {
switch (*s) {
case 'd': /* delay */
case 'D':
sleep(2);
break;
case 'c': /* don't output CR at end of string */
case 'C':
nocr = TRUE;
break;
case 'r': /* carriage return */
case 'R':
case 'm':
case 'M':
swrite("\r", 1);
break;
case 'n': /* new line */
case 'N':
swrite("\n", 1);
break;
case 'b': /* backspace */
case 'B':
swrite("\b", 1);
break;
case 't': /* tab */
case 'T':
swrite("\t", 1);
break;
case 's': /* space */
case 'S':
swrite(" ", 1);
break;
case 'z': /* set serial port speed */
case 'Z':
SIOSpeed(++s);
while (*s != '\0' && *s != '\\')
s++;
if (*s == '\\')
s++;
break;
default: /* ordinary character */
swrite(s, 1);
}
last = '\0';
}
else if (*s != '\\') /* backslash */
swrite(s, 1);
else
last = *s;
s++;
}
return nocr;
} /*writestr*/
/*
s e n d s t r
Send line of login sequence
*/
static void sendstr(str)
char *str;
{
printmsg(2, "sending %s", str);
if (equaln(str, "BREAK", 5)) {
int nulls;
nulls = atoi(&str[5]);
if (nulls <= 0 || nulls > 10)
nulls = 3;
ssendbrk(nulls); /* send a break signal */
return;
}
if (equal(str, "EOT")) {
swrite(EOTMSG, strlen(EOTMSG));
return;
}
if (equal(str, "\"\""))
*str = '\0';
if (!equal(str,"")) {
if (!writestr(str)) {
swrite("\r", 1);
}
} else
swrite("\r", 1);
return;
} /*sendstr*/
/*
s e n d e x p e c t
*/
static int sendexpect(send, expect, timeout)
char *send, *expect;
int timeout;
{
sendstr(send);
return expectstr(expect, timeout);
} /*sendexpect*/
/*
d i a l
*/
static int dial()
{
char buf[4];
if (!equal(flds[FLD_TYPE], "HAYES")) {
printmsg(0, "dial: unsupported dialer %s", flds[FLD_TYPE]);
return FALSE;
}
printmsg(3, "dial: calling host %s", rmtname);
if (openline(S_sysdevice, "2400"))
return FALSE;
printmsg(0, "hayes: trying 2400");
if (sendexpect("ATZ", "OK", 2) != TRUE) {
sendexpect("\\d+++\\d", "OK", 2);
if (sendexpect("ATZ", "OK", 2) != TRUE) {
printmsg(0, "hayes: trying 1200");
SIOSpeed("1200");
if (sendexpect("ATZ", "OK", 2) != TRUE) {
sendexpect("\\d+++\\d", "OK", 2);
if (sendexpect("ATZ", "OK", 2) != TRUE)
return FALSE;
}
}
}
printmsg(0, "hayes: got modem response");
/*(sendstr("\\d\\dATS7=30");
expectstr("OK", 40);*/
sendstr("\\d\\dATX4\\c");
if (sendexpect(S_sysspeed, "CONNECT ", 40) == TRUE) {
printmsg(3, "hayes: got CONNECT");
if (sread(buf, 4, 4) == 4) {
printmsg(3, "hayes: speed select %s", buf);
/* set speed appropriately */
SIOSpeed(buf);
}
return TRUE;
}
else
return FALSE;
} /*dial*/
/*
c a l l u p
script processor - nothing fancy!
*/
char callup()
{
char *exp, *alternate;
int ok, i;
printmsg(0, "callup: calling host \"%s\"", rmtname);
if (!equal(flds[FLD_TYPE], "DIR")) {
if (dial() == FALSE)
return 'G';
}
else
if (openline(S_sysdevice, S_sysspeed))
return 'G';
for (i = FLD_EXPECT; i < kflds; i += 2) {
exp = flds[i];
printmsg(2, "expecting %d of %d \"%s\"", i, kflds, exp);
ok = FALSE;
while (ok != TRUE) {
alternate = strchr(exp, '-');
if (alternate != nil(char))
*alternate++ = '\0';
ok = expectstr(exp, 30);
if (ok) {
printmsg(2, "got that");
break;
} else
printmsg(1, "got ???");
if (alternate == nil(char)) {
printmsg(0, "LOGIN FAILED");
return 'Y';
}
exp = strchr(alternate, '-');
if (exp != nil(char))
*exp++ = '\0';
printmsg(0, "sending alternate");
sendstr(alternate);
} /*while*/
printmsg(2, "sending %d of %d \"%s\"", i + 1, kflds, flds[i + 1]);
sleep(1);
sendstr(flds[i + 1]);
} /*for*/
return 'P';
} /*callup*/
/*
s c a n d i r
Scan spooling directory for C.* files for the remote host (rmtname)
returns:
A - abort
Y - can't open file
S - ok
Q - no files
*/
char scandir(remote)
char *remote;
{
char callpfx[40];
int pfxlen;
DIR *dirp;
struct direct *dp;
if ((dirp = opendir(spooldir)) == nil(DIR)) {
printmsg(0, "scandir: couldn't opendir() %s", spooldir);
return 'A';
}
sprintf(callpfx, CALLFILE, remote);
pfxlen = strlen(callpfx);
printmsg(5, "scandir: \"%s\"", callpfx);
while ((dp = readdir(dirp)) != nil(struct direct)) {
printmsg(10, " %s", dp->d_name);
if (equaln(callpfx, dp->d_name, pfxlen)) {
printmsg(5, "scandir: matched");
strcpy(workfile, dp->d_name);
closedir(dirp);
if ((fwork = FOPEN(workfile, "r", TEXT)) == nil(FILE))
return 'Y';
return 'S';
}
}
printmsg(5, "scandir: not matched");
closedir(dirp);
return 'Q';
} /*scandir*/
/*
x s c a n d i r
Scan spooling directory for X.* files, for 'uuxqt'.
*/
char *xscandir(xname)
char xname[];
{
DIR *dirp;
struct direct *dp;
int pfxlen;
if ((dirp = opendir(spooldir)) == nil(DIR)) {
printmsg(0, "xscandir: couldn't opendir() %s", spooldir);
return nil(char);
}
printmsg(5, "xscandir: \"%s\"", XQTPFX);
pfxlen = strlen(XQTPFX);
while ((dp = readdir(dirp)) != nil(struct direct)) {
printmsg(10, " %s",
dp->d_name, XQTPFX);
if (equaln(XQTPFX, dp->d_name, pfxlen)) {
printmsg(5, "xscandir: matched");
strcpy(xname, dp->d_name);
closedir(dirp);
return xname;
}
}
printmsg(5, "xscandir: not matched");
closedir(dirp);
return nil(char);
} /*xscandir*/
#if FALSE
/*
slowrite - comunication slow write. needed for auto-baud modems
*/
void slowrite(st)
char *st;
{
int len, j;
char c;
len = strlen(st);
printmsg(2, "sent %s", st);
for (j = 0; j < len; j++) {
swrite(&st[j], 1);
ddelay(80000);
}
} /*slowrite*/
/*
d d e l a y
*/
void ddelay(dtime)
int dtime;
{
int i, j;
for (i = 0; i < dtime; i++) {
}
} /*ddelay*/
#endif